#ifndef VSQLPROCESSOR_H
#define VSQLPROCESSOR_H

#include <sqlite3.h>

#include "VBackgroundWorker.h"

#define SQL_PROCESSOR_DELAY 50
#define SQL_WAITRESULT_DELAY 50
#define SQL_LIST_LOCK_DELAY 50
#define SQL_TIMEOUT_INFINITY (-1)
#define SQL_GARBAGE_RELEASER_TIMEOUT 20000

typedef std::vector<std::string> sql_headers_t;
typedef std::vector<std::vector<std::string> > sql_table_t;
typedef std::vector<std::string> sql_rows_t;
typedef std::vector<std::string> sql_column_t;

typedef struct sql_result_table_t
{
    sql_headers_t headers;
    sql_table_t data;

public:
    sql_result_table_t() {}
    sql_result_table_t(const sql_result_table_t& f)
    {
        headers = f.headers;
        data = f.data;
    }
} sql_result_table_t;

typedef struct sql_result_column_t
{
    std::string header;
    sql_column_t column;

public:
    sql_result_column_t() {}
    sql_result_column_t(const sql_result_column_t& f)
    {
        header = f.header;
        column = f.column;
    }
} sql_result_column_t;

typedef struct sql_result_row_t
{
    sql_rows_t rows;

public:
    sql_result_row_t() {}
    sql_result_row_t(const sql_result_row_t& f)
    {
        rows = f.rows;
    }
} sql_result_row_t;

typedef struct sql_result_value_t
{
    std::string value;

public:
    sql_result_value_t() {}
    sql_result_value_t(const sql_result_value_t& f)
    {
        value = f.value;
    }
} sql_result_value_t;

typedef struct sql_result_t
{
    int id;
    int type;
    void* content;
    int errorcode;
    int processedtime;
    std::string errormsg;
public:
    sql_result_t() : id(0), type(0), content(NULL), errorcode(0), processedtime(0) {}
    sql_result_t(const sql_result_t& f)
    {
        id = f.id;
        type = f.type;
        content = f.content;
        errorcode = f.errorcode;
        errormsg = f.errormsg;
        processedtime = f.processedtime;
    }
} sql_result_t;

typedef struct sql_event_t
{
    int id;
    int type;
    int result_type;
    int priority;
    std::string sql;
public:
    sql_event_t() : id(0), type(0), result_type(0), priority(0) {}
    sql_event_t(const sql_event_t& f)
    {
        id = f.id;
        type = f.type;
        result_type = f.result_type;
        priority = f.priority;
        sql = f.sql;
    }


} sql_event_t;

typedef enum
{
    SQL_REQUEST_NONE,
    SQL_REQUEST_DDL,
    SQL_REQUEST_DML,
    SQL_REQUEST_DQL,
    SQL_REQUEST_OTHER
} sql_request_type_t;

typedef enum
{
    SQL_RESULT_NONE,        // 返回运行的状态(错误码)
    SQL_RESULT_NONEEDED,    // 无需返回
    SQL_RESULT_TABLE,       // 返回表
    SQL_RESULT_ROW,         // 返回一行(一个条目)
    SQL_RESULT_COLUMN,      // 返回一列
    SQL_RESULT_VALUE,       // 返回一个值
    SQL_RESULT_OTHER        // 保留
} sql_result_type_t;

typedef enum
{
    SQL_PRIORITY_INSTANT = -1,
    SQL_PRIORITY_HIGH = 0,
    SQL_PRIORITY_MIDDLEHIGH = 1,
    SQL_PRIORITY_MIDDLE = 2,
    SQL_PRIORITY_MIDDLELOW = 3,
    SQL_PRIORITY_LOW = 4,
    SQL_PRIORITY_DEFAULT = SQL_PRIORITY_MIDDLE
} sql_priority_t;

typedef enum
{
    LOCK_NOREADY = 0,
    LOCK_LOCKED = 1,
    LOCK_UNLOCKED = 2
} sql_lock_status_t;

typedef std::list<sql_event_t> sql_event_list_t;
typedef std::list<sql_result_t> sql_result_list_t;



class VSqlProcessor:
    public VBackgroundWorker
{
public:  // public interface
    bool putevent(
        int request_type,
        int result_type,
        int priority,
        const std::string& sql,
        int* id);
    bool getresult(
        int id,
        sql_result_t* result,
        int timeout);

    bool open_database(const std::string& db_path);
    void close_database();


public: // public static interface
    static void free_result_content(sql_result_t* result);

    static sql_result_table_t* result_to_table(const sql_result_t*);
    static sql_result_column_t* result_to_column(const sql_result_t*);
    static sql_result_value_t* result_to_value(const sql_result_t*);
    static sql_result_row_t* result_to_row(const sql_result_t*);


protected: // unaccessable constructor and destructor
    VSqlProcessor();
    ~VSqlProcessor();


protected:  // private used
    bool getevent(sql_event_t* event);
    void putresult(const sql_result_t& result);
    void lock_event_list();
    void unlock_event_list();
    void lock_result_list();
    void unlock_result_list();

    bool verify_event(int* sql_type, int* ret_type, int* priority, const std::string& sql) const;
    bool check_event_list(int event_id);
    void enhance_event_priority(int event_id);
    int garbage_realese();


protected: // static callback
    static int thread_callback(VSqlProcessor* pthis);
    static int sqlite_callback(void* result, int argc, char** argv, char** colname);
    static void set_processing_id(int id);
    static int get_processing_id();
    static void init_result(sql_result_t* result);

public:  // static interface
    static VSqlProcessor* init_instance();
    static void kill_instance();
    static VSqlProcessor* get_this();

protected:
    sql_event_list_t _event_list;
    sql_result_list_t _result_list;
    int _processing_id;
    int _event_list_lock;
    int _result_list_lock;

    sqlite3* _mysqlite;

protected:  // static protcted member variables
    static VSqlProcessor* _pthis;
};

#endif // VSQLPROCESSOR_H
